﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Num = System.Int32;

namespace FAfx.SpectrumFish.Hardware
{
    public class Memory : FAfx.SpectrumFish.Interfaces.Hardware.IMemory
    {
        private Num[] _mem = new Num[0x10000];
        public Num[] Mem { 
            get {return _mem;}
            set {_mem = value;}
        }

        internal Memory(Num[] rom)
        {
            for (var i = 0x0000; i < 0x4000; i++)
            {
                _mem[i] = rom[i];
            }
            for (var i = 0x4000; i < 0x10000; i++)
            {
                _mem[i] = 0;
            }
        }

        public override bool Equals(Object obj)
        {
            bool ret = false;

            // Check for null values and compare run-time types.
            if (obj == null || GetType() != obj.GetType())
                return ret;

            Memory t = (Memory)obj;
            var hasMismatches = Enumerable.Range(0, 0x10000).ToList().Exists(x => _mem[x] != t._mem[x]);
            return !hasMismatches;

        }
        
        public Num[] getMem()
        {
            return _mem;
        }

        public Num readbyte(Num addr)
        {
            return _mem[addr];
        }

        public void writebyte(Num addr, Num val)
        {
            if (addr < 0x4000) return;
            _mem[addr] = val;
        }

        public Num[] getScreen()
        {
            return _mem.Slice(0x4000, 0x5B00);
        }
    }

    internal static class Extensions
    {
        /// <summary>
        /// Get the array slice between the two indexes.
        /// ... Inclusive for start index, exclusive for end index.
        /// </summary>
        internal static T[] Slice<T>(this T[] source, int start, int end)
        {
            // Handles negative ends.
            if (end < 0)
            {
                end = source.Length + end;
            }
            int len = end - start;

            // Return new array.
            T[] res = new T[len];
            for (int i = 0; i < len; i++)
            {
                res[i] = source[i + start];
            }
            return res;
        }
    }
}
